import CustomRenderV3 from "../CustomRenderV3/CustomRenderV3";

const {ccclass, property, executeInEditMode} = cc._decorator;

@ccclass
@executeInEditMode
export default class CustomRenderDebugger extends cc.Component {

    @property(cc.Graphics)
    vertexDebugger: cc.Graphics = null;

    @property(cc.Graphics)
    lineDebugger: cc.Graphics = null;

    @property(cc.Node)
    indiceDebugger: cc.Node = null;
    
    vertexArray: cc.Vec2[];
    indiceLabels: {};

    onLoad () {

    }

    onDisable () {
        this.vertexDebugger.clear();
        this.vertexDebugger.node.removeAllChildren(true);
        this.lineDebugger.clear();
        this.indiceDebugger.removeAllChildren(true);
        this.vertexArray = [];
    }

    start () {
        this.plot();
    }

    pRotateByAngle (v, pivot, angle) {
        var r = v.sub(pivot);
        var cosa = Math.cos(angle), sina = Math.sin(angle);
        var t = r.x;
        r.x = t * cosa - r.y * sina + pivot.x;
        r.y = t * sina + r.y * cosa + pivot.y;
        return r;
    }

    getTriangleCentroid(vertex0, vertex1, vertex2){
        var centerX = (vertex0.x + vertex1.x + vertex2.x) / 3;
        var centerY = (vertex0.y + vertex1.y + vertex2.y) / 3;
        return cc.v2(centerX, centerY);
    }

    plotArrow (from:cc.Vec2, to:cc.Vec2, pivotLerp:number, angle:number, length:number) {
        let pivot1 = from.lerp(to, pivotLerp);
        let pivot2 = from.lerp(to, pivotLerp - length / cc.Vec2.distance(from , to));
        let arrowEdge1 = this.pRotateByAngle(pivot1, pivot2, Math.PI + cc.misc.degreesToRadians(angle));
        let arrowEdge2 = this.pRotateByAngle(pivot1, pivot2, Math.PI - cc.misc.degreesToRadians(angle));

        this.lineDebugger.moveTo(pivot1.x, pivot1.y);
        this.lineDebugger.lineTo(arrowEdge1.x, arrowEdge1.y);

        this.lineDebugger.moveTo(pivot1.x, pivot1.y);
        this.lineDebugger.lineTo(arrowEdge2.x, arrowEdge2.y);

        this.lineDebugger.moveTo(arrowEdge1.x, arrowEdge1.y);
        this.lineDebugger.lineTo(arrowEdge2.x, arrowEdge2.y);
    }

    plot () {
        let customRender = this.node.getComponent(cc.RenderComponent);
        if (!customRender) {
            cc.error("missing customRender");
        }
        if (!this.vertexDebugger || !this.lineDebugger || !this.indiceDebugger) {
            return;
        }

        this.vertexDebugger.clear();
        this.vertexDebugger.node.removeAllChildren(true);
        this.lineDebugger.clear();
        this.indiceDebugger.removeAllChildren(true);
        this.vertexArray = [];

        //@ts-ignore
        let _renderData = customRender._assembler._renderData;
        // cc.log(_renderData.vDatas[0]);
        
        // vertex + index label
        // this.indiceLabels = {};
        
        let vertexCounter = 0;
        for (let i = 0; i < _renderData.vDatas[0].length; i += 5) {
            let vx = _renderData.vDatas[0][i];
            let vy = _renderData.vDatas[0][i + 1];
            //
            this.vertexArray.push(cc.v2(vx, vy));
            // 
            this.vertexDebugger.circle(vx, vy, this.vertexDebugger.lineWidth);
            //
            let indiceNode = this.vertexDebugger.node.getChildByName("indiceNode-" + vx + "-" + vy);
            if (indiceNode) {
                indiceNode.getComponent(cc.Label).string += ("," + (vertexCounter).toString());
            }
            else {
                // indiceNode = new cc.Node("indiceNode-" + vx + "-" + vy);
                // indiceNode.setPosition(vx, vy);
                // let indiceLabel = indiceNode.addComponent(cc.Label);
                // indiceLabel.fontSize = 12;
                // indiceLabel.string = (vertexCounter).toString();
                // indiceLabel.horizontalAlign = cc.Label.HorizontalAlign.CENTER;
                // indiceLabel.verticalAlign = cc.Label.VerticalAlign.CENTER;
                // this.vertexDebugger.node.addChild(indiceNode);
            }
            //
            vertexCounter += 1;
        }
        this.vertexDebugger.fill();

        // triangle + ordered line
        let arrowLength = 50;
        for (let i = 0; i < _renderData.iDatas[0].length; i += 3) {
            let indice0 = _renderData.iDatas[0][i];
            let indice1 = _renderData.iDatas[0][i + 1];
            let indice2 = _renderData.iDatas[0][i + 2];
            let vertex0 = this.vertexArray[indice0];
            let vertex1 = this.vertexArray[indice1];
            let vertex2 = this.vertexArray[indice2];
            let triangleCenter = this.getTriangleCentroid(vertex0, vertex1, vertex2);
            let vertexShrink0 = triangleCenter.lerp(vertex0, 0.9);
            let vertexShrink1 = triangleCenter.lerp(vertex1, 0.9);
            let vertexShrink2 = triangleCenter.lerp(vertex2, 0.9);
            // 
            this.lineDebugger.moveTo(vertexShrink0.x, vertexShrink0.y);
            this.lineDebugger.lineTo(vertexShrink1.x, vertexShrink1.y);
            this.plotArrow(vertexShrink0, vertexShrink1, 0.3, 20, 5);

            this.lineDebugger.moveTo(vertexShrink1.x, vertexShrink1.y);
            this.lineDebugger.lineTo(vertexShrink2.x, vertexShrink2.y);
            this.plotArrow(vertexShrink1, vertexShrink2, 0.3, 20, 5);

            this.lineDebugger.moveTo(vertexShrink2.x, vertexShrink2.y);
            this.lineDebugger.lineTo(vertexShrink0.x, vertexShrink0.y);
            this.plotArrow(vertexShrink2, vertexShrink0, 0.3, 20, 5);
        }
        this.lineDebugger.stroke();
    }

    update () {
        this.plot();
    }
}
